package org.brakepedal.server.support.bluetooth;

import io.netty.buffer.ByteBuf;
import lombok.Getter;
import org.brakepedal.server.pojo.BtInfo;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import java.io.Closeable;
import java.io.IOException;

/**
 * Date: 2024/3/31 15:18
 *
 * @author Huanyu Mark
 */
@Lazy
@Getter
@Component
@Scope("prototype")
public class BtService extends BtInfo implements MultiArgsObjectProvider<BtDecodeBroker>, Closeable {
    private final ApplicationContext ctx;

    private final String connectionUrl;

    private volatile BtDecodeBroker decodeBroker;

    private volatile BtEncodeBroker encodeBroker;

    private final String encodeBrokerBeanName;

    private final String decodeBrokerBeanName;

    public BtService(ApplicationContext ctx, ServiceRecord serviceRecord, UUID serviceUUID) throws IOException {
        super(serviceRecord.getHostDevice());
        this.ctx = ctx;
        this.connectionUrl = serviceRecord.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
        encodeBrokerBeanName = ctx.getBeanNamesForType(BtEncodeBroker.class)[0];
        decodeBrokerBeanName = ctx.getBeanNamesForType(BtDecodeBroker.class)[0];
        ByteBuf
    }

    public BtEncodeBroker getEncoder()  {
        if(encodeBroker != null) {
            return encodeBroker;
        }
        synchronized (this) {
            if(encodeBroker != null) {
                return encodeBroker;
            }
            encodeBroker = new BtEncodeBroker(this);
            ctx.getAutowireCapableBeanFactory().configureBean(encodeBroker,encodeBrokerBeanName);
            return encodeBroker;
        }
    }

    public BtDecodeBroker getDecoder(){
        if(decodeBroker != null) {
            return decodeBroker;
        }
        synchronized (this) {
            if(decodeBroker != null) {
                return decodeBroker;
            }
            decodeBroker = new BtDecodeBroker(this);
            ctx.getAutowireCapableBeanFactory().configureBean(decodeBroker,decodeBrokerBeanName);
            return decodeBroker;
        }
    }

    @Override
    public @NotNull BtDecodeBroker getObject() {
        return getDecoder();
    }

    @Override
    public void close() throws IOException {
        if(decodeBroker != null){
            decodeBroker.close();
        }
        if(encodeBroker != null) {
            encodeBroker.close();
        }
    }

    @Override
    public @NotNull BtDecodeBroker getObject(Object... args) throws BeansException {
        if(args.length == 0) {
            throw new IllegalArgumentException("args must not be empty");
        }
        if(!(args[0] instanceof BtService service)) {
            throw new IllegalArgumentException("args[0] must be BtService");
        }
        return new BtDecodeBroker(service);
    }
}
